package ve.com.wayoyo.wuml_case.DibujoDiagramas;

import java.io.FileOutputStream;
import java.io.IOException;

import ve.com.wayoyo.wuml_case.NuevoDiagrama;
import ve.com.wayoyo.wuml_case.R;
import ve.com.wayoyo.wuml_case.UserPref;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;

public class VistaDiagrama extends View {
	
	public final static int IDLE = 0;
	public final static int SCROLLING = 1;
	public final static int SCALING = 2;
	public final static int CREATING_ITEM = 3;
	public final static int MOVING_ITEM = 4;
	public final static int ITEM_SELECTED = 5;
	public final static int CONNECTING_ITEMS = 6;
	public final static int CONNECTOR_SELECTED = 7;
	public final static int RESET = 99;
	
	
	private static float MIN_ZOOM = 0.5f;
	private static float MAX_ZOOM = 3.0f;
	private static VistaDiagrama _instance;
	
	private int _xOffset = 0;
    private int _yOffset = 0;
    private float _Scale = 1.0f;

    
    private int _xTouch = 0;
    private int _yTouch = 0;
    
    private int _currentState = IDLE;
	
	private Diagrama _diagrama;
	private Paint _backgroundPaint;
	private Paint _imagePaint;
	
	private ScaleGestureDetector detector;
//	private String titulo = null;
	private boolean showHelpNewElement;
	private boolean _moveFlag;
	

	
	//Bitmaps de los cuadros de ayuda
	Bitmap HelpNewElementBitmap = BitmapFactory.decodeResource(this.getContext().getResources(),R.drawable.cuadroayuda1);
	

	public VistaDiagrama(Context context,Diagrama diagrama){
		super(context);
		_backgroundPaint = new Paint();
		_backgroundPaint.setColor(UserPref.getInstancia().getColorFondoDiagramas());
		this._diagrama = diagrama;
		_imagePaint = new Paint();
		detector = new ScaleGestureDetector(getContext(), new ScaleListener());
		_instance = this;
	}
	
	public Diagrama getDiagrama(){
		return _diagrama;
	}
	
	public void set_diagrama(Diagrama _diagrama) {
		this._diagrama = _diagrama;
		invalidate();
	}

	@Override
	protected void onDraw(Canvas c){
		super.onDraw(c);
		c.drawPaint(_backgroundPaint);
		_diagrama.Dibujar(c,_xOffset , _yOffset, _Scale);
		if(showHelpNewElement == true){
			c.drawBitmap(HelpNewElementBitmap, (c.getWidth()/2)-200, (c.getHeight()/2)-200, _imagePaint);
		}
	}
	
	@Override
	public boolean onTouchEvent (MotionEvent event) {
		detector.onTouchEvent(event);
		NuevoDiagrama diag = (NuevoDiagrama) this.getContext();	  
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
            // store the current touch coordinates for scroll calculation
            _xTouch = (int) event.getX();
            _yTouch = (int) event.getY();
            if(_currentState != CONNECTING_ITEMS && _currentState != CONNECTOR_SELECTED){
            	_diagrama.resetFocus();
            }   
			if(_currentState == CREATING_ITEM)
        	{			
		        Componente comp = new CompClase("");	
				Point anchor = new Point();
				
				anchor.set((int)((_xTouch)/(_Scale)-_xOffset), (int)((_yTouch)/(_Scale)-_yOffset));
				comp.setAnchor(anchor);
        		TituloComponente myDialog = new TituloComponente(this.getContext(),"Indique el nombre","Titulo",comp);
		        myDialog.show();
        		_currentState = RESET;
        		showHelpNewElement = false;
        		invalidate();
        	}else if (_currentState == CONNECTING_ITEMS){
        		Point touchPoint = new Point();
        		touchPoint.set((int)((_xTouch)/(_Scale)-_xOffset), (int)((_yTouch)/(_Scale)-_yOffset));
        		_currentState = _diagrama.checkOnTouch(touchPoint,"Connect");
        		if(_currentState == IDLE){
        			_currentState = CONNECTING_ITEMS;
        		}
        		invalidate();
        	}else if(_currentState == CONNECTOR_SELECTED ){
        		
        	}else{
        		Point touchPoint = new Point();
        		touchPoint.set((int)((_xTouch)/(_Scale)-_xOffset), (int)((_yTouch)/(_Scale)-_yOffset));
        		_currentState = _diagrama.checkOnTouch(touchPoint,"Select");
        		if(_currentState == ITEM_SELECTED){
        	        diag.cambioMenu(NuevoDiagrama.MENU_CLASE);
        		}else if(_currentState == CONNECTOR_SELECTED){
        			diag.cambioMenu(NuevoDiagrama.MENU_CONECTOR);
        			_moveFlag = true;
        		}else{
        			diag.cambioMenu(NuevoDiagrama.MENU_PRINCIPAL);	
        		}
        		invalidate();
        	}
        }else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            // touch starts moving, set the flag
        	if(_currentState == IDLE){
	            _currentState = SCROLLING;
        	}else if(_currentState ==  ITEM_SELECTED){
        		_currentState = MOVING_ITEM;
        	}
        	
        	if( _currentState == SCROLLING || _currentState == CONNECTING_ITEMS || _currentState == CONNECTOR_SELECTED ){ 	
	            // get the new offset
        		if(Math.abs(_xTouch - (int) event.getX()) > 10 || Math.abs(_yTouch - (int) event.getY()) > 10){
        			_moveFlag = true;
        		}
        		_xOffset -= _xTouch - (int) event.getX();
        		_yOffset -= _yTouch - (int) event.getY();
        		invalidate();
        	}
        	if(_currentState == MOVING_ITEM){
        		_diagrama.moverItemSeleccionado((int)(-(_xTouch - (int) event.getX())/_Scale),(int)(-(_yTouch - (int) event.getY())/_Scale));
        		invalidate();
        	}
    
         // store the last position
            _xTouch = (int) event.getX();
            _yTouch = (int) event.getY();
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if(_currentState == CONNECTOR_SELECTED && !_moveFlag ){
            	_diagrama.resetFocus();
            	Point touchPoint = new Point();
        		touchPoint.set((int)((_xTouch)/(_Scale)-_xOffset), (int)((_yTouch)/(_Scale)-_yOffset));
        		_currentState = _diagrama.checkOnTouch(touchPoint,"Select");
        		if(_currentState == ITEM_SELECTED){
        	        diag.cambioMenu(NuevoDiagrama.MENU_CLASE);
        		}else if(_currentState == CONNECTOR_SELECTED){
        			diag.cambioMenu(NuevoDiagrama.MENU_CONECTOR);
        		}else if(_currentState == IDLE){
        			diag.cambioMenu(NuevoDiagrama.MENU_PRINCIPAL);
        		}
        		invalidate();
            }
            if(_currentState == CONNECTING_ITEMS && !_moveFlag){
            	_currentState = ITEM_SELECTED;
            	_diagrama.getSelectedItem().set_currentState(Componente.SELECTED);
            	invalidate();
            }
        	_moveFlag = false;
        }
		
		return true;
	}
	
	
	private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

		@Override
		public boolean onScale(ScaleGestureDetector detector) {
				_currentState = SCALING;
				_Scale *= detector.getScaleFactor();
				_Scale = Math.max(MIN_ZOOM, Math.min(_Scale, MAX_ZOOM));
				invalidate();
			return true;
		}

	}
	
	public static VistaDiagrama getVista(){
		return _instance;
	}
	
	public static void resetFocusStatico(){
		_instance.getDiagrama().resetFocus();
		_instance.invalidate();
	}

	public void Conexion() {
		_currentState = CONNECTING_ITEMS;
		_diagrama.getSelectedItem().set_currentState(Componente.CONNECTING);
		invalidate();
	}

	public void nuevaClase()
	{
		_currentState= CREATING_ITEM;
		showHelpNewElement = true;
		invalidate();
	}
	
	public void agregarAtributo() {
		AtributoComponente myDialog = new AtributoComponente(this.getContext());		
        myDialog.show();
		invalidate();
	}
	
	public void modificarAtributo() {
		AtributoModif myDialog = new AtributoModif(getContext());
		myDialog.show();
		invalidate();
	}
	
	public void Guardar(String FileName){
		
	}
	public void ExportarPNG(String FileName,int sideMargins){
		_diagrama.resetFocus();
		Canvas canvas = null;
		Bitmap bmpBase = null;
		FileOutputStream fos = null;

		bmpBase = Bitmap.createBitmap(_diagrama.getDiagramWidth()+(sideMargins*2),_diagrama.getDiagramHeight()+(sideMargins*2) , Bitmap.Config.ARGB_8888);
		canvas = new Canvas(bmpBase);
		super.onDraw(canvas);
		canvas.drawPaint(_backgroundPaint);
		_diagrama.Dibujar(canvas,_diagrama.getDiagramXoffSet()+sideMargins , _diagrama.getDiagramYoffSet()+sideMargins, 1);
		try
		{
		    fos = new FileOutputStream(Environment.getExternalStorageDirectory()+"/"+FileName+".png");
		    bmpBase.compress(Bitmap.CompressFormat.PNG, 100, fos);
		    Toast.makeText(getContext(), "Listo", Toast.LENGTH_LONG).show();
		    fos.flush();
		    fos.close();
		    fos = null;
		}
		catch (IOException e)
		{
		    System.out.print(e.getMessage());
		    Toast.makeText(getContext(), "Se jodio esa vaina", Toast.LENGTH_LONG).show();
		}
		finally
		{
		    if (fos != null)
		    {
		        try
		        {
		            fos.close();
		            fos = null;
		        }
		        catch (IOException e)
		        {
		            e.printStackTrace();
		        }
		    }
		}
	}
	
	public void agregarMetodo() {
		NuevoMetodoComponente myDialog = new NuevoMetodoComponente(this.getContext());		
        myDialog.show();
		invalidate();		
	}

	public void modificarMetodo(ArrayAdapter<String> adapter) {
		SeleccionarMetodoComponente myDialog = new SeleccionarMetodoComponente(this.getContext(), adapter);		
        myDialog.show();
		invalidate();
	}

	public void editarRelacion() {
		EditarConector myDialog = new EditarConector(this.getContext());		
        myDialog.show();
		invalidate();
	}

}


